home *** CD-ROM | disk | FTP | other *** search
-
-
- // ---------------------------------------------------------------------
- //
- // NAVIGATR.C - QuickTime for Windows
- //
- // Version 1.0
- //
- // (c) Copyright 1988-1994 Apple Computer, Inc. All Rights Reserved.
- //
- // ---------------------------------------------------------------------
-
-
- #include <windows.h>
- #include <commdlg.h>
- #include <qtw.h>
- #include <dos.h>
- #include <math.h>
- #include <direct.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys\types.h>
- #include <sys\stat.h>
- #include "navigatr.hr"
- #include "fileexts.rh"
-
- #define MAX_DELAY 500
- #define REPEAT_PAN 1
- #define SQR(x) ((x)*(x))
-
- long FAR PASCAL __export WndProc (HWND, UINT, WPARAM, LPARAM);
- static int NEAR MyGetZone (HWND);
- static LONG NEAR MyPanMovie (HWND, int);
- static UINT NEAR MyCalcDelay (HWND, int);
- static VOID NEAR MyShowFrame (HWND);
- static int NEAR Flip16 (int);
-
- static MovieFile mfMovie;
- static Movie mMovie;
- static MovieController mcController;
- static HWND hWnd;
- static HCURSOR hNormal;
- static HCURSOR hCursor[CUR_MAX];
- static RECT rcZone[CUR_MAX];
- static int cxZone, cyZone;
- static RECT rcMovie;
- static char szAppName[] = "NAVIGATR";
- static short cxFrame, cyFrame, bBidirectional, sLoopSize, sScaleFactor;
- static LONG xFrame, yFrame, lFrame;
- static BOOL bNAVG, bNAVg;
-
-
- // WinMain
- // ---------------------------------------------------------------------
- int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
- LPSTR lpszCmdParam, int nCmdShow)
- {
- MSG msg;
- WNDCLASS wndclass;
- RECT rcDesktop, rcController;
- char szDir[_MAX_DIR];
- char szMovieTitle[_MAX_PATH];
- char szMovie[_MAX_PATH];
- char szTitle[_MAX_PATH];
- char szFilter[_MAX_PATH];
- UserData udMovie;
- HGLOBAL hMem;
- LONG lSize;
- OPENFILENAME ofn;
- struct _stat st;
- short far * s;
- short v;
- char * p;
- int i;
-
- // If parameter is missing, look for a movie with the same name
- // as the executable. If this isn't found, use the standard
- // open dialog to get a movie name
-
- if (lstrlen (lpszCmdParam) == 0) {
- GetModuleFileName (hInstance, szMovie, sizeof (szMovie));
- p = strrchr (szMovie, '.');
- strcpy (p, ".MOV");
- if (_stat (szMovie, &st)) {
- _getcwd (szDir, sizeof (szDir));
- szMovie[0] = '\0';
- memset (&ofn, 0, sizeof(OPENFILENAME));
- ofn.lStructSize = sizeof(OPENFILENAME);
- ofn.hwndOwner = 0;
- ofn.lpstrFilter = CommonGetFileFilter (hInstance, (WORD) COMMON_MOVIES_FILEEXT, szFilter, sizeof szFilter);
- ofn.nFilterIndex = 1;
- ofn.lpstrFile = szMovie;
- ofn.nMaxFile = sizeof(szMovie);
- ofn.lpstrFileTitle = szMovieTitle;
- ofn.nMaxFileTitle = sizeof(szMovieTitle);
- ofn.lpstrInitialDir = szDir;
- ofn.lpstrTitle = "Select a Movie to Navigate";
- ofn.Flags = OFN_HIDEREADONLY;
- if (GetOpenFileName (&ofn) == 0)
- return 0;
- }
- _strupr (szMovie);
- }
-
- // Otherwise, treat the command line parameter as the
- // root directory.
-
- else {
- lstrcpy (szMovie, lpszCmdParam);
- _strupr (szMovie);
- }
-
- // Derive the title
-
- _splitpath (szMovie, NULL, NULL, szTitle, NULL);
- AnsiLower (szTitle);
-
- // Establish links to QuickTime for Windows
-
- if (QTInitialize (NULL)) {
- MessageBox (NULL, "QTInitialize failure", szAppName, MB_OK);
- return 0;
- }
-
- // Allocate memory required for playing movies
-
- if (EnterMovies ()) {
- MessageBox (NULL, "EnterMovies failure", szAppName, MB_OK);
- return 0;
- }
-
- // Instantiate movie
-
- if (OpenMovieFile (szMovie, &mfMovie, OF_READ) != noErr) {
- MessageBox (NULL, "OpenMovieFile failure", szAppName, MB_OK);
- PostQuitMessage (0);
- return 0;
- }
-
- NewMovieFromFile (&mMovie, mfMovie, NULL, NULL, 0, NULL);
- CloseMovieFile (mfMovie);
-
- // Extract NAVG user data
-
- if (((udMovie = GetMovieUserData (mMovie)) != NULL)
- && ((hMem = GlobalAlloc (GMEM_MOVEABLE, 128)) != NULL)) {
-
- // New format
-
- if (GetUserData (udMovie, &hMem, QTFOURCC('N','A','V','G'), 1, &lSize) == noErr) {
- s = (short FAR *) GlobalLock (hMem);
- v = *s++;
- v = *s++; cxFrame = Flip16 (v);
- v = *s++; cyFrame = Flip16 (v) - 1;
- v = *s++; bBidirectional = ((Flip16 (v)) == 1);
- v = *s++; sLoopSize = Flip16 (v);
- v = *s++; sScaleFactor = Flip16 (v);
- GlobalUnlock (hMem);
- bNAVG = TRUE;
- }
-
- // Old format
-
- else if (GetUserData (udMovie, &hMem, QTFOURCC('N','A','V','g'), 1, &lSize) == noErr) {
- s = (short FAR *) GlobalLock (hMem);
- v = *s++;
- v = *s++; cyFrame = Flip16 (v);
- v = *s++; cxFrame = Flip16 (v);
- v = *s++; bBidirectional = ((Flip16 (v)) == 1);
- sScaleFactor = (short) (GetMovieTimeScale (mMovie) / 60);
- GlobalUnlock (hMem);
- bNAVg = TRUE;
- }
- }
-
- if (hMem) GlobalFree (hMem);
-
- if (!bNAVG && !bNAVg) {
- MessageBox (NULL, "This movie cannot be navigated!", szAppName, MB_OK);
- PostQuitMessage (0);
- return 0;
- }
-
- // Initialize the starting location
-
- lFrame = (LONG) GetMovieDuration (mMovie) / 2;
- xFrame = (lFrame / sScaleFactor) % cxFrame;
- yFrame = (lFrame / sScaleFactor) / cxFrame;
-
- // Load the zone cursors
-
- hNormal = LoadCursor (NULL, IDC_ARROW);
-
- for (i = CUR_N; i < CUR_MAX; i++)
- hCursor[i] = LoadCursor (hInstance, MAKEINTRESOURCE (i));
-
- // Register and create main window
-
- if (!hPrevInstance) {
- wndclass.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
- wndclass.lpfnWndProc = WndProc;
- wndclass.cbClsExtra = 0;
- wndclass.cbWndExtra = 0;
- wndclass.hInstance = hInstance;
- wndclass.hIcon = LoadIcon (NULL,IDI_APPLICATION);
- wndclass.hCursor = hNormal;
- wndclass.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH);
- wndclass.lpszMenuName = NULL;
- wndclass.lpszClassName = szAppName;
- if (!RegisterClass (&wndclass)) {
- MessageBox (NULL, "RegisterClass failure", szAppName, MB_OK);
- return 0;
- }
- }
-
- hWnd = CreateWindow(szAppName, szAppName, WS_CAPTION | WS_SYSMENU |
- WS_CLIPCHILDREN | WS_OVERLAPPED, CW_USEDEFAULT, CW_USEDEFAULT,
- CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
-
- if (hWnd == NULL) {
- MessageBox (NULL, "CreateWindow failure", szAppName, MB_OK);
- return 0;
- }
-
- // Instantiate the movie controller
-
- GetMovieBox (mMovie, &rcMovie);
- OffsetRect(&rcMovie, -rcMovie.left, -rcMovie.top);
- mcController = NewMovieController (mMovie, &rcMovie,
- mcTopLeftMovie + mcScaleMovieToFit + mcNotVisible, hWnd);
-
- // Initialize the zone rectangles
-
- cxZone = rcMovie.right / 3;
- cyZone = rcMovie.bottom / 3;
-
- rcZone[CUR_N].left = rcMovie.left + cxZone;
- rcZone[CUR_N].right = rcMovie.right - cxZone;
- rcZone[CUR_N].top = rcMovie.top;
- rcZone[CUR_N].bottom = rcMovie.top + cyZone;
-
- rcZone[CUR_NE].left = rcMovie.right - cxZone;
- rcZone[CUR_NE].right = rcMovie.right;
- rcZone[CUR_NE].top = rcMovie.top;
- rcZone[CUR_NE].bottom = rcMovie.top + cyZone;
-
- rcZone[CUR_E].left = rcMovie.right - cxZone;
- rcZone[CUR_E].right = rcMovie.right;
- rcZone[CUR_E].top = rcMovie.top + cyZone;
- rcZone[CUR_E].bottom = rcMovie.bottom - cyZone;
-
- rcZone[CUR_SE].left = rcMovie.right - cxZone;
- rcZone[CUR_SE].right = rcMovie.right;
- rcZone[CUR_SE].top = rcMovie.bottom - cyZone;
- rcZone[CUR_SE].bottom = rcMovie.bottom;
-
- rcZone[CUR_S].left = rcMovie.left + cxZone;
- rcZone[CUR_S].right = rcMovie.right - cxZone;
- rcZone[CUR_S].top = rcMovie.bottom - cyZone;
- rcZone[CUR_S].bottom = rcMovie.bottom;
-
- rcZone[CUR_SW].left = rcMovie.left;
- rcZone[CUR_SW].right = rcMovie.left + cxZone;
- rcZone[CUR_SW].top = rcMovie.bottom - cyZone;
- rcZone[CUR_SW].bottom = rcMovie.bottom;
-
- rcZone[CUR_W].left = rcMovie.left;
- rcZone[CUR_W].right = rcMovie.left + cxZone;
- rcZone[CUR_W].top = rcMovie.top + cyZone;
- rcZone[CUR_W].bottom = rcMovie.bottom - cyZone;
-
- rcZone[CUR_NW].left = rcMovie.left;
- rcZone[CUR_NW].right = rcMovie.left + cxZone;
- rcZone[CUR_NW].top = rcMovie.top;
- rcZone[CUR_NW].bottom = rcMovie.top + cyZone;
-
- rcZone[CUR_CENTER].left = rcMovie.left + cxZone;
- rcZone[CUR_CENTER].right = rcMovie.right - cxZone;
- rcZone[CUR_CENTER].top = rcMovie.top + cyZone;
- rcZone[CUR_CENTER].bottom = rcMovie.bottom - cyZone;
-
- // Make the window just big enough for the controller
-
- MCGetControllerBoundsRect (mcController, &rcController);
- AdjustWindowRect (&rcController, WS_CAPTION | WS_OVERLAPPED, FALSE);
- OffsetRect(&rcController, -rcController.left, -rcController.top);
- GetWindowRect (GetDesktopWindow (), &rcDesktop);
- SetWindowPos (hWnd, 0,
- (rcDesktop.right - rcController.right) / 2,
- (rcDesktop.bottom - rcController.bottom) / 2,
- rcController.right, rcController.bottom, SWP_NOZORDER);
-
- // Make the main window visible
-
- SetWindowText (hWnd, szTitle);
- ShowWindow (hWnd, nCmdShow);
- UpdateWindow (hWnd);
- MCDoAction (mcController, mcActionPlay, (LPVOID) MAKELFIXED (0, 0));
- SetMovieActive (mMovie, TRUE);
- MyShowFrame (hWnd);
- InvalidateRect (hWnd, &rcMovie, FALSE);
- MCDoAction (mcController, mcActionSetFlags, (LPVOID) mcFlagsUseWindowPalette);
-
- // Play the movie
-
- while (GetMessage (&msg, NULL, 0, 0)) {
- TranslateMessage (&msg);
- DispatchMessage (&msg);
- }
-
- // Destroy movie controller
-
- DisposeMovieController (mcController);
-
- // Destroy movie
-
- DisposeMovie (mMovie);
-
- // Destroy the zone cursors
-
- for (i = CUR_N; i <= CUR_MAX; i++)
- DestroyCursor (hCursor[i]);
-
- // Cut the connections to QuickTime for Windows
-
- ExitMovies ();
- QTTerminate ();
-
- // Return to Windows
-
- return msg.wParam;
- }
-
-
- // WndProc
- // ---------------------------------------------------------------------
- long FAR PASCAL __export WndProc (HWND hWnd, UINT message, WPARAM wParam,
- LPARAM lParam)
- {
- RECT rcClient;
- PAINTSTRUCT ps;
- int i;
-
- // Drive the movie controller
-
- if (message != WM_LBUTTONDBLCLK)
- MCIsPlayerMessage (mcController, hWnd, message, wParam, lParam);
-
- // Process the windows message
-
- switch (message) {
-
- // All done!
-
- case WM_DESTROY:
- PostQuitMessage (0);
- return 0;
-
- // (Primitive) keyboard interface
-
- case WM_KEYDOWN:
- switch (wParam) {
- case VK_UP: return MyPanMovie (hWnd, CUR_N);
- case VK_DOWN: return MyPanMovie (hWnd, CUR_S);
- case VK_LEFT: return MyPanMovie (hWnd, CUR_W);
- case VK_RIGHT: return MyPanMovie (hWnd, CUR_E);
- default: return 0;
- }
-
- // Click down
-
- case WM_LBUTTONDOWN:
- GetClientRect (hWnd, &rcClient);
- ClientToScreen (hWnd, (POINT FAR *) &rcClient.left);
- ClientToScreen (hWnd, (POINT FAR *) &rcClient.right);
- ClipCursor (&rcClient);
- SetCapture (hWnd);
- i = MyGetZone (hWnd);
- SetCursor (hCursor[i]);
- return MyPanMovie (hWnd, i);
-
- // Click up
-
- case WM_LBUTTONUP:
- KillTimer (hWnd, REPEAT_PAN);
- ClipCursor (NULL);
- ReleaseCapture ();
- SetCursor (hNormal);
- return 0;
-
- // Mouse movement
-
- case WM_MOUSEMOVE:
- if (hWnd == GetCapture ())
- SetCursor (hCursor[MyGetZone(hWnd)]);
- return 0;
-
- // In case we have to paint this movie
-
- case WM_PAINT:
- if (!BeginPaint (hWnd, &ps))
- return 0;
- EndPaint (hWnd, &ps);
- return 0;
-
- // Repeat pan
-
- case WM_TIMER:
- return MyPanMovie (hWnd, MyGetZone (hWnd));
-
- }
-
- // Return to Windows
-
- return DefWindowProc (hWnd, message, wParam, lParam);
- }
-
-
- // MyGetZone
- // ---------------------------------------------------------------------
- static int NEAR MyGetZone (HWND hWnd)
- {
- POINT pt;
- int i;
-
- // What is the current cursor position?
-
- GetCursorPos (&pt);
- ScreenToClient (hWnd, &pt);
-
- // In which zone does it lie?
-
- for (i = CUR_N; i <= CUR_MAX; i++) {
- if (PtInRect (&rcZone[i], pt))
- break;
- }
-
- // Return zone to caller
-
- return i;
-
- }
-
-
- // MyPanMovie
- // ---------------------------------------------------------------------
- static LONG NEAR MyPanMovie (HWND hWnd, int i)
- {
- // Stop any prior timer
-
- KillTimer (hWnd, REPEAT_PAN);
-
- // Calculate new position
-
- switch (i) {
-
- case CUR_N: --yFrame; break;
- case CUR_E: ++xFrame; break;
- case CUR_S: ++yFrame; break;
- case CUR_W: --xFrame; break;
- case CUR_NE: ++xFrame; --yFrame; break;
- case CUR_SE: ++xFrame; ++yFrame; break;
- case CUR_SW: --xFrame; ++yFrame; break;
- case CUR_NW: --xFrame; --yFrame; break;
-
- }
-
- // Adjust for wrapping
-
- if (xFrame < 0) xFrame = cxFrame - 1;
- if (xFrame >= cxFrame) xFrame = 0;
- if (yFrame < 0) yFrame = 0;
- if (yFrame >= cyFrame) yFrame = cyFrame - 1;
-
- // Now, show the right frame
-
- MyShowFrame (hWnd);
-
- // Start up again quickly ...
-
- SetTimer (hWnd, REPEAT_PAN, MyCalcDelay (hWnd, i), NULL);
-
- // Return to caller
-
- return 0;
-
- }
-
-
- // MyCalcDelay
- // ---------------------------------------------------------------------
- static UINT NEAR MyCalcDelay (HWND hWnd, int i)
- {
- POINT pt;
- UINT uiDelay;
-
- // What is the current cursor position?
-
- GetCursorPos (&pt);
- ScreenToClient (hWnd, &pt);
-
- // Calculate delay time
-
- switch (i) {
-
- case CUR_N: uiDelay = ((pt.y - rcMovie.top) * MAX_DELAY)
- / (cyZone - rcMovie.top);
- break;
-
- case CUR_E: uiDelay = ((rcMovie.right - pt.x) * MAX_DELAY)
- / (rcMovie.right - cxZone);
- break;
-
- case CUR_S: uiDelay = ((rcMovie.bottom - pt.y) * MAX_DELAY)
- / (rcMovie.bottom - cyZone);
- break;
-
- case CUR_W: uiDelay = ((pt.x - rcMovie.left) * MAX_DELAY)
- / (cxZone - rcMovie.left);
- break;
-
- case CUR_NE: uiDelay = (UINT) ((sqrt (SQR (rcMovie.right - pt.x)
- + SQR (pt.y - rcMovie.top)) * MAX_DELAY)
- / sqrt (SQR (cxZone) + SQR (cyZone)));
- break;
-
- case CUR_SE: uiDelay = (UINT) ((sqrt (SQR (rcMovie.right - pt.x)
- + SQR (rcMovie.bottom - pt.y)) * MAX_DELAY)
- / sqrt (SQR (cxZone) + SQR (cyZone)));
- break;
-
- case CUR_SW: uiDelay = (UINT) ((sqrt (SQR (pt.x - rcMovie.left)
- + SQR (rcMovie.bottom - pt.y)) * MAX_DELAY)
- / sqrt (SQR (cxZone) + SQR (cyZone)));
- break;
-
- case CUR_NW: uiDelay = (UINT) ((sqrt (SQR (pt.x - rcMovie.left)
- + SQR (pt.y - rcMovie.top)) * MAX_DELAY)
- / sqrt (SQR (cxZone) + SQR (cyZone)));
- break;
-
- default: uiDelay = MAX_DELAY;
- break;
-
- }
-
- // Return to caller
-
- return uiDelay;
-
- }
-
-
- // MyShowFrame
- // ---------------------------------------------------------------------
- static VOID NEAR MyShowFrame (HWND hWnd)
- {
- TimeRecord tr;
-
- // Get the current movie time
-
- GetMovieTime (mMovie, &tr);
-
- // Is this new style?
-
- if (bNAVG) {
- if (! bBidirectional || ((yFrame % 2) == 0))
- tr.value.dwLo = ((yFrame * cxFrame) + xFrame) * sScaleFactor;
- else tr.value.dwLo = ((yFrame * cxFrame) + (cxFrame - xFrame - 1)) * sScaleFactor;
- }
-
- // Or old style?
-
- else if (bNAVg) {
- if (! bBidirectional || ((yFrame % 2) == 0))
- tr.value.dwLo = ((yFrame * cxFrame) + xFrame) * sScaleFactor;
- else tr.value.dwLo = ((yFrame * cxFrame) + (cxFrame - xFrame - 1)) * sScaleFactor;
- }
-
- // Set the new movie time
-
- if (MCDoAction (mcController, mcActionGoToTime, (LPVOID) &tr) != mcOK)
- return;
-
- }
-
-
- // Flip16
- // ---------------------------------------------------------------------
- #pragma optimize ("ceglnpqiw", off)
- static int NEAR Flip16 (int v)
- {
-
- _asm {
- mov ax,v
- xchg ah,al
- mov v,ax
- }
-
- return v;
- }
-